package com.winit.openapi.sms;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.spi.SPIException;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.sms.common.SmsUtils;
import com.winit.openapi.sms.validator.OnLineRechargeFieldValidator;
import com.winit.openapi.util.BeanUtils;
import com.winit.openapi.util.DateUtil;
import com.winit.sms.spi.base.bankaccount.BankAccountService;
import com.winit.sms.spi.base.bankaccount.command.QueryBankAccountByPayChannelCommand;
import com.winit.sms.spi.base.bankaccount.vo.BankAccountVo;
import com.winit.sms.spi.common.command.IdCommand;
import com.winit.sms.spi.common.vo.PageVo;
import com.winit.sms.spi.wallet.onlinerecharge.OnLineRechargeService;
import com.winit.sms.spi.wallet.onlinerecharge.RechargeChannelService;
import com.winit.sms.spi.wallet.onlinerecharge.command.ConfirmRechargeFailedCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.ConfirmRechargeSuccessCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.CreateIpnMessageCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.CreateOnLineRechargeCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.ModifyOnLineRechargeCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.PayoneerIpcnCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.QueryOnLineRechargeByNoCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.QueryOnLineRechargeCommand;
import com.winit.sms.spi.wallet.onlinerecharge.command.QueryRechargeChannelCommand;
import com.winit.sms.spi.wallet.onlinerecharge.vo.OnLineRechargeVo;
import com.winit.sms.spi.wallet.onlinerecharge.vo.RechargeChannelVo;
import com.winit.sms.spi.wallet.pay.BpepPayService;
import com.winit.sms.spi.wallet.pay.CertifyInfoService;
import com.winit.sms.spi.wallet.pay.OperationRecordService;
import com.winit.sms.spi.wallet.pay.command.BpepNoticeCommand;
import com.winit.sms.spi.wallet.pay.command.BpepPayCommand;
import com.winit.sms.spi.wallet.pay.command.CreateCertifyInfoCommand;
import com.winit.sms.spi.wallet.pay.command.CreateOperationRecordCommand;
import com.winit.sms.spi.wallet.pay.command.ModifyCertifyInfoByIdCommand;
import com.winit.sms.spi.wallet.pay.command.QueryCertifyInfoCommand;
import com.winit.sms.spi.wallet.pay.vo.BpepPayRetVo;
import com.winit.sms.spi.wallet.pay.vo.CertifyInfoVo;
import com.winit.sms.spi.wallet.pay.vo.OperationRecordVo;

/**
 * 线上充值
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * jun.lu 	1.0  		2015年12月24日 	Created
 * 
 * </pre>
 * @since 1.
 */

@Controller
@RequestMapping("/sms/onLineRecharge")
public class OnLineRechargeController extends BaseController {

    private static Logger          logger = LoggerFactory.getLogger(OnLineRechargeController.class);
    @Resource
    private OnLineRechargeService  onLineRechargeService;

    @Resource
    private CertifyInfoService     certifyInfoService;

    @Resource
    private BpepPayService         bpepPayService;
    @Resource
    private BankAccountService     bankAcctService;
    @Resource
    private OperationRecordService operationRecordService;
    @Resource
    private RechargeChannelService rechargeChannelService;

    /**
     * 创建线上充值单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createOnLineRecharge")
    public String createOnLineRecharge(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
    	try {
    		OnLineRechargeFieldValidator.validCreateField(SmsUtils.toJsonObject(requestMsg.getData()));
            CreateOnLineRechargeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
                CreateOnLineRechargeCommand.class);
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>createOnLineRecharge:" + command.toString());
            Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
            if (bpartner == null) {
                logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
                return ERROR;
            }

            command.setCustomerCode(bpartner.getValue());
            //查询支付渠道
            if (null != command.getBankAccountNo()) {
                IdCommand idCommand = new IdCommand();
                idCommand.setId(command.getBankAccountNo());
                BankAccountVo bankAccountVo = bankAcctService.queryBankAccountById(idCommand);
                if (bankAccountVo != null) {
                    command.setPayChannel(bankAccountVo.getPayChannel());
                } else {
                    logger.info("根据银行账号id：｛｝查询支付渠道为空！", command.getBankAccountNo());
                }
            } else if (!StringUtils.isBlank(command.getPayChannel())) {
                QueryBankAccountByPayChannelCommand queryBankCmd = new QueryBankAccountByPayChannelCommand();
                queryBankCmd.setPayChannel(command.getPayChannel());
                queryBankCmd.setCurrencyCode(command.getCurrencyCode());
                queryBankCmd.setOrgId(CommandContext.getContext().getOrgId());
                queryBankCmd.setCtx(CommandContext.getContext());
                BankAccountVo bankAccountVo = bankAcctService.queryBankAccountByPayChannel(queryBankCmd);
                if (bankAccountVo != null) {
                    command.setBankAccountNo(bankAccountVo.getId());
                }
            }

            //校验充值金额
            QueryRechargeChannelCommand rechargeChannelCommand = new QueryRechargeChannelCommand();
            rechargeChannelCommand.setPayChannel(command.getPayChannel());
            RechargeChannelVo rechargeChannelVo = rechargeChannelService.queryRechargeChannelByPayChannel(rechargeChannelCommand);
            if (rechargeChannelVo != null) {
                //充值渠道最低充值金额
                BigDecimal minRechargeAmount = rechargeChannelVo.getMinRechargeAmount();
                //充值渠道最低高值金额
                BigDecimal maxRechargeAmount = rechargeChannelVo.getMaxRechargeAmount();
                if(null != minRechargeAmount){
                	if (command.getPayAmount().subtract(minRechargeAmount).compareTo(BigDecimal.ZERO) < 0) {
                        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>充值金额不能小于"+minRechargeAmount+command.getCurrencyCode()+"！");
                        throw new ApiException(ErrorCode.PAY_AMOUNT_NOT_LT,minRechargeAmount,command.getCurrencyCode());
                    }
                }
                if(null != maxRechargeAmount){
                	if (command.getPayAmount().subtract(maxRechargeAmount).compareTo(BigDecimal.ZERO) > 0) {
                        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>充值金额不能大于"+minRechargeAmount+command.getCurrencyCode()+"！");
                        throw new ApiException(ErrorCode.PAY_AMOUNT_NOT_GT,maxRechargeAmount,command.getCurrencyCode());
                    }
                }
            }
            
            String onlineRechargeNo = onLineRechargeService.createOnLineRecharge(command);
            // 返回充值单号
            Map<String, String> data = new HashMap<String, String>();
            data.put("onlineRechargeNo", onlineRechargeNo);
            responseMsg.setData(data);
		} catch (SPIException e) {
			logger.error("createOnLineRecharge-----》创建线上充值单异常",e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
		}
        return SUCCESS;
    }

    /**
     * 线上充值失败
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/confirmRechargeFailed")
    public String confirmRechargeFailed(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        ConfirmRechargeFailedCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            ConfirmRechargeFailedCommand.class);
        onLineRechargeService.confirmRechargeFailed(command);
        return SUCCESS;
    }

    @RequestMapping(value = "/modifyOnRechargeStatusCFI")
    public String modifyOnRechargeStatusCFI(@ModelAttribute RequestMsg requestMsg,
                                            @ModelAttribute ResponseMsg responseMsg) {

        ModifyOnLineRechargeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            ModifyOnLineRechargeCommand.class);
        onLineRechargeService.modifyOnLineRechargeStatusCFI(command);
        return SUCCESS;
    }

    /**
     * 线上充值成功
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/confirmRechargeSuccess")
    public String confirmRechargeSuccess(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        ConfirmRechargeSuccessCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            ConfirmRechargeSuccessCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        try {
            onLineRechargeService.confirmRechargeSuccess(command);
        } catch (Exception e) {
            logger.error(e.getMessage());
            responseMsg.setCode(ErrorCode.SYSTEM_ERROR);
            responseMsg.setMsg(e.getMessage());
            return ERROR;
        }
        String onlineRechargeNo = command.getOnlineRechargeNo();
        QueryOnLineRechargeByNoCommand queryOnLineRechargeByNoCommand = new QueryOnLineRechargeByNoCommand();
        queryOnLineRechargeByNoCommand.setOnlineRechargeNo(onlineRechargeNo);
        OnLineRechargeVo onLineRechargeVo = onLineRechargeService.queryOnLineRechargeByNo(queryOnLineRechargeByNoCommand);
        // 返回状态
        Map<String, String> data = new HashMap<String, String>();
        data.put("status", onLineRechargeVo.getStatus());
        return SUCCESS;
    }

    /**
     * 创建IPN消息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     * @throws ParseException
     * @throws UnsupportedEncodingException 
     */
    @RequestMapping(value = "/createIpnMessage")
    public String createIpnMessage(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg)
                                                                                                                  throws ParseException,
                                                                                                                  UnsupportedEncodingException {
        CreateIpnMessageCommand command = new CreateIpnMessageCommand();
        JSONObject json = (JSONObject) requestMsg.getData();
        Object objMsg = json.get("Message");
        if (null != objMsg) {
            command.setMessage(String.valueOf(objMsg));
            Map<String, String> splitMap = parseMessage(String.valueOf(objMsg));

            BigDecimal mc_fee = BigDecimal.ZERO;// 手续费
            BigDecimal mc_gross = BigDecimal.ZERO;// 金额
            if (org.apache.commons.lang3.StringUtils.isNotBlank(splitMap.get("mc_fee"))) {
                mc_fee = new BigDecimal(splitMap.get("mc_fee")).setScale(2, BigDecimal.ROUND_HALF_UP);
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(splitMap.get("mc_gross"))) {
                mc_gross = new BigDecimal(splitMap.get("mc_gross")).setScale(2, BigDecimal.ROUND_HALF_UP);
            }
            command.setTxnId(splitMap.get("txn_id"));
            command.setPaymentStatus(splitMap.get("payment_status"));// 付款状态
            if (null != splitMap.get("payer_email")) { // 付款人邮箱
                command.setPayerEmail(splitMap.get("payer_email"));
            }
            if (null != splitMap.get("receiver_email")) { // 收款人邮箱
                command.setReceiverEmail(splitMap.get("receiver_email"));
            }
            command.setMcCurrency(splitMap.get("mc_currency"));// 币种
            command.setMcFee(mc_fee);// 手续费
            command.setMcGross(mc_gross);// 金额
        }
        Object objId = json.get("onlineRechargeId");
        if (null != objId) {
            command.setOnlineRechargeId(String.valueOf(objId));// 线上充值单号
        }
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        Long count = onLineRechargeService.createIpnMessage(command);
        responseMsg.setData(count);
        return SUCCESS;
    }

    /**
     * 解析消息
     * 
     * @param Message
     * @return
     * @throws UnsupportedEncodingException 
     */
    public static Map<String, String> parseMessage(String Message) throws UnsupportedEncodingException {
        String[] messages = null;
        Map<String, String> map = new HashMap<String, String>();
        if (StringUtils.isBlank(Message) || (messages = Message.split("&")).length == 0) {
            return map;
        }
        for (String message : messages) {
            if (StringUtils.isBlank(message)) {
                continue;
            }
            String[] nvps = URLDecoder.decode(message, "UTF-8").split("=");
            map.put(nvps[0], nvps.length > 1 ? org.apache.commons.lang3.StringUtils.trim(nvps[1]) : "");
        }
        return map;
    }

    /**
     * 分页查询线上充值单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     * @throws ParseException
     */
    @RequestMapping(value = "/pageOnLineRecharge")
    public String pageOnLineRecharge(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg)
                                                                                                                    throws ParseException {
        QueryOnLineRechargeCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryOnLineRechargeCommand.class);
        PageVo pageVo = SmsUtils.SetPageParams(requestMsg.getData());
        command.setPageVo(pageVo);
        Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        if (null != command.getPayEndDate()) {
            command.setPayEndDate(DateUtil.spliceDate(command.getPayEndDate()));
        }
        Page<OnLineRechargeVo> pagelist = onLineRechargeService.pageOnLineRecharge(command);
        Map<String, Object> data = SmsUtils.setPageData(pagelist);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 根据付款人id和付款人类型和客户编码进行认证信息查询 
     * 这个查询是查询认证状态是通过的，并且是最新的一条认证记录
     * @param requestMsg
     * @param responseMsg
     * @return
     * @throws ParseException
     */
    @RequestMapping(value = "/queryCeritifyInfoByCertifyTrue")
    public String queryCeritifyInfoByCertifyTrue(@ModelAttribute RequestMsg requestMsg,
                                                 @ModelAttribute ResponseMsg responseMsg) {
        QueryCertifyInfoCommand command = SmsUtils.toJavaObject(requestMsg.getData(), QueryCertifyInfoCommand.class);
        //设置认证通过
        command.setCertifyType("Y");
        List<CertifyInfoVo> vo = certifyInfoService.queryCertifyInfo(command);
        Map<String, Object> data = new HashMap<String, Object>();
        if (null != vo && vo.size() > 0) {
            data.put("certifyInfo", vo.get(0));
        } else {
            data.put("certifyInfo", null);
        }
        responseMsg.setData(data);
        return SUCCESS;
    }

    @RequestMapping(value = "/queryCeritfyInfoList")
    public String queryCeritfyInfoList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryCertifyInfoCommand command = SmsUtils.toJavaObject(requestMsg.getData(), QueryCertifyInfoCommand.class);
        //设置认证通过
        command.setCertifyType("Y");
        List<CertifyInfoVo> vo = certifyInfoService.queryCertifyInfoList(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("certifyInfo", vo);
        responseMsg.setData(data);
        return SUCCESS;
    }

    @RequestMapping(value = "/bpepQuickValidate")
    public String bpepQuickValidate(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        BpepPayCommand command = SmsUtils.toJavaObject(requestMsg.getData(), BpepPayCommand.class);
        try {
            if (org.apache.commons.lang3.StringUtils.isNotBlank(command.getAdvanceName())) {
                command.setAdvanceName(command.getAdvanceName().replaceAll("\\s*", ""));
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(command.getMobile())) {
                command.setMobile(command.getMobile().replaceAll("\\s*", ""));
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(command.getCertNo())) {
                command.setCertNo(command.getCertNo().replaceAll("\\s*", ""));
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(command.getBankCode())) {
                command.setBankCode(command.getBankCode().replaceAll("\\s*", ""));
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(command.getBankCardCode())) {
                command.setBankCardCode(command.getBankCardCode().replaceAll("\\s*", ""));
            }

            OperationRecordVo operationRecordVo = bpepPayService.bpepQuickValidate(command);
            responseMsg.setData(operationRecordVo);
        } catch (SPIException e) {
            logger.error("OnLineRechargeController->bpepQuickValidate(),command:" + command.toString(), e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        return SUCCESS;
    }

    @RequestMapping(value = "/bpepPay")
    public String bpepPay(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        BpepPayCommand command = SmsUtils.toJavaObject(requestMsg.getData(), BpepPayCommand.class);
        try {
            BpepPayRetVo vo = bpepPayService.bpepPay(command);
            responseMsg.setData(vo);
        } catch (SPIException e) {
            logger.error("OnLineRechargeController->bpepPay(),command:" + command.toString(), e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        return SUCCESS;
    }

    @RequestMapping(value = "/bpepNotice")
    public String bpepNotice(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object object = requestMsg.getData();
        if (object == null || !(object instanceof JSONObject)) {
            return ERROR;
        }
        BpepNoticeCommand cmd = new BpepNoticeCommand();
        JSONObject json = (JSONObject) object;
        if (json.containsKey("BANKCODE")) {
            cmd.setBANKCODE(convertObject2String(json.get("BANKCODE")));
        }
        if (json.containsKey("COMMENT1")) {
            cmd.setCOMMENT1(convertObject2String(json.get("COMMENT1")));
        }
        if (json.containsKey("COMMENT2")) {
            cmd.setCOMMENT2(convertObject2String(json.get("COMMENT2")));
        }
        if (json.containsKey("CUSTCODE")) {
            cmd.setCUSTCODE(convertObject2String(json.get("CUSTCODE")));
        }
        if (json.containsKey("FEE")) {
            cmd.setFEE(convertObject2String(json.get("FEE")));
        }
        if (json.containsKey("ORDERAMOUNT")) {
            cmd.setORDERAMOUNT(convertObject2String(json.get("ORDERAMOUNT")));
        }
        if (json.containsKey("ORDERID")) {
            cmd.setORDERID(convertObject2String(json.get("ORDERID")));
        }
        if (json.containsKey("ORDERSTATUS")) {
            cmd.setORDERSTATUS(convertObject2String(json.get("ORDERSTATUS")));
        }
        if (json.containsKey("ORGLOGINCODE")) {
            cmd.setORGLOGINCODE(convertObject2String(json.get("ORGLOGINCODE")));
        }
        if (json.containsKey("PERENTFLAG")) {
            cmd.setPERENTFLAG(convertObject2String(json.get("PERENTFLAG")));
        }
        if (json.containsKey("PLATCODE")) {
            cmd.setPLATCODE(convertObject2String(json.get("PLATCODE")));
        }
        if (json.containsKey("SIGNSTR")) {
            cmd.setSIGNSTR(convertObject2String(json.get("SIGNSTR")));
        }
        if (json.containsKey("TRANSDATE")) {
            cmd.setTRANSDATE(convertObject2String(json.get("TRANSDATE")));
        }
        if (json.containsKey("TRSSEQ")) {
            cmd.setTRSSEQ(convertObject2String(json.get("TRSSEQ")));
        }
        if (json.containsKey("interfaceType")) {
            cmd.setInterfaceType(convertObject2Long(json.get("interfaceType")));
        }
        //        BpepNoticeCommand command = SmsUtils.toJavaObject(requestMsg.getData(), BpepNoticeCommand.class);
        try {
            BpepPayRetVo vo = bpepPayService.bpepNotice(cmd);
            responseMsg.setData(vo);
        } catch (SPIException e) {
            logger.error("OnLineRechargeController->bpepNotice(),command:" + object.toString(), e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        return SUCCESS;
    }

    private String convertObject2String(Object object) {
        if (null == object) {
            return "";
        }
        return object.toString();
    }

    private Long convertObject2Long(Object object) {
        if (null == object) {
            return -1L;
        }
        Long intValue = 0L;
        try {
            intValue = Long.parseLong(object.toString());
        } catch (NumberFormatException e) {
            intValue = -1L;
            logger.error("OnLineRechargeController->convertObject2Int()转换字符串到数字异常！", e);
        }
        return intValue;
    }

    /**
     * Payoneer支付成功后IPCN
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/payoneerPayIpcn")
    public String payoneerPayIpcn(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        logger.info("################Payoneer支付IPCN处理开始##########################");
        PayoneerIpcnCommand command = SmsUtils.toJavaObject(requestMsg.getData(), PayoneerIpcnCommand.class);
        CommandContext ctx = CommandContext.getContext();
        ctx.setUsername("system");
        ctx.setOrgId(1000000L);
        command.setCtx(ctx);
        try {
            // 校验返回参数，如果字段值为空则不合法
            if (!validPayoneerIpcnPara(command)) {
                logger.error("Payoneer支付IPCN返回参数不合法：" + command.toString());
                throw new ApiException(ErrorCode.PAYONEER_IPCN_PARA_ERROR);
            }
            logger.info("Payoneer支付IPCN参数：" + command.toString());
            String onlineRechargeNo = command.getIntPaymentId();
            QueryOnLineRechargeByNoCommand queryOnLineRechargeByNoCommand = new QueryOnLineRechargeByNoCommand();
            queryOnLineRechargeByNoCommand.setOnlineRechargeNo(onlineRechargeNo);
            OnLineRechargeVo onLineRechargeVo = onLineRechargeService.queryOnLineRechargeByNo(queryOnLineRechargeByNoCommand);

            // 如果数据库不存在该线上充值单或返回参数与充值单数据不匹配，直接返回错误
            if (null == onLineRechargeVo) {
                logger.error("Payoneer支付IPCN返回参数与充值单不匹配：" + command.toString());
                throw new ApiException(ErrorCode.PAYONEER_IPCN_PARA_ERROR);
            }

            logger.info("OnLineRechargeController->payoneerPayIpcn()充值单状态值:" + onLineRechargeVo.getStatus());
            // 如果充值单是完成状态，回写Payoneer交易流水号
            if (SmsUtils.OLRECHARGE_STATUS_SUSS.equals(onLineRechargeVo.getStatus())) {
                ModifyOnLineRechargeCommand modifyCmd = new ModifyOnLineRechargeCommand();
                modifyCmd.setOnlineRechargeNo(onlineRechargeNo);
                modifyCmd.setTransactionCode(command.getPayoneerPaymentId());
                modifyCmd.setCtx(ctx);
                onLineRechargeService.modifyOnLineRechargeByNo(modifyCmd);
            } else {
                // 如果充值单不是完成状态，更改充值单状态为完成并回写交易流水号
                ConfirmRechargeSuccessCommand cmd = new ConfirmRechargeSuccessCommand();
                cmd.setOnlineRechargeNo(onlineRechargeNo);
                cmd.setTransactionCode(command.getPayoneerPaymentId());
                cmd.setCtx(ctx);
                onLineRechargeService.confirmRechargeSuccess(cmd);
            }
        } catch (SPIException e) {
            logger.error(e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        logger.info("################Payoneer支付IPCN处理结束##########################");
        return SUCCESS;
    }

    /**
     * 根据充值单号查询详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryOnLineRechargeByNo")
    public String queryOnLineRechargeByNo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        QueryOnLineRechargeByNoCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            QueryOnLineRechargeByNoCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        try {
            OnLineRechargeVo onLineRechargeVo = onLineRechargeService.queryOnLineRechargeByNo(command);
            responseMsg.setData(onLineRechargeVo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            responseMsg.setCode(ErrorCode.SYSTEM_ERROR);
            responseMsg.setMsg(e.getMessage());
            return ERROR;
        }
        return SUCCESS;
    }

    /**
     * 根据交易id查询paypal详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/modifyOnLineRechargeByPayPal")
    public String modifyOnLineRechargeStatusByPayPal(@ModelAttribute RequestMsg requestMsg,
                                                     @ModelAttribute ResponseMsg responseMsg) {
        ConfirmRechargeSuccessCommand command = SmsUtils.toJavaObject(requestMsg.getData(),
            ConfirmRechargeSuccessCommand.class);
        CommandContext ctx = CommandContext.getContext();
        command.setCtx(ctx);
        try {
            onLineRechargeService.modifyOnLineRechargeStatusByPayPal(command);
        } catch (Exception e) {
            logger.error(e.getMessage());
            responseMsg.setCode(ErrorCode.SYSTEM_ERROR);
            responseMsg.setMsg(e.getMessage());
            return ERROR;
        }
        return SUCCESS;
    }

    /**
     * 创建银盈通调用记录
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createOperationRecord")
    public String createOperationRecord(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        CreateCertifyInfoCommand command = SmsUtils.toJavaObject(requestMsg.getData(), CreateCertifyInfoCommand.class);
        try {
            OnLineRechargeFieldValidator.validCreateOperationRecordField(SmsUtils.toJsonObject(requestMsg.getData()));
            CreateOperationRecordCommand createRecordCmd = new CreateOperationRecordCommand();
            createRecordCmd.setInterfaceType(1L);
            createRecordCmd.setPayChannel(command.getPayChannel());
            createRecordCmd.setInterfaceDirection("TO_EB");
            createRecordCmd.setCallResult(command.getCallResult());
            Long result = operationRecordService.createOperationRecord(createRecordCmd);

            //查询认证通过的信息
            QueryCertifyInfoCommand queryCertifyInfoCommand = BeanUtils.copyProperties(command,
                QueryCertifyInfoCommand.class);
            List<CertifyInfoVo> list = certifyInfoService.queryCertifyInfo(queryCertifyInfoCommand);
            if (CollectionUtils.isEmpty(list)) {
                //创建银盈通认证信息
                certifyInfoService.createCertifyInfo(command);
            }
            if (CollectionUtils.isNotEmpty(list) && list.get(0) != null && "Y".equals(command.getCertifyType())
                && "N".equals(list.get(0).getCertifyType())) {
                //创建银盈通认证信息
                CommandContext ctx = CommandContext.getContext();
                ModifyCertifyInfoByIdCommand modifyCertifyInfoByIdCommand = new ModifyCertifyInfoByIdCommand();
                modifyCertifyInfoByIdCommand.setCertifyType(command.getCertifyType());
                modifyCertifyInfoByIdCommand.setId(list.get(0).getId());
                modifyCertifyInfoByIdCommand.setCtx(ctx);
                certifyInfoService.modifyCertifyInfoById(modifyCertifyInfoByIdCommand);
            }
            responseMsg.setData(result);
        } catch (SPIException e) {
            logger.error("OnLineRechargeController->createOperationRecord(),command:" + command.toString(), e);
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
        }
        return SUCCESS;
    }

    private boolean validPayoneerIpcnPara(PayoneerIpcnCommand command) {
        if (StringUtils.isBlank(command.getPayeeId())) {
            return false;
        }

        if (StringUtils.isBlank(command.getPayoneerPaymentId())) {
            return false;
        }

        if (StringUtils.isBlank(command.getIntPaymentId())) {
            return false;
        }

        if (null == command.getAmount() || BigDecimal.ZERO.compareTo(command.getAmount()) != -1) {
            return false;
        }
        return true;

    }
    
    /**
     * 更新线上充值单 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/modifyOnLineRechargeByNo")
    public String modifyOnLineRechargeByNo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
    	ModifyOnLineRechargeCommand modifyCmd = new ModifyOnLineRechargeCommand();
    	try {
    		modifyCmd = SmsUtils.toJavaObject(requestMsg.getData(), ModifyOnLineRechargeCommand.class);
    		CommandContext ctx = new CommandContext();
    		modifyCmd.setCtx(ctx);
    		int retValue =onLineRechargeService.modifyOnLineRechargeByNo(modifyCmd);
    		responseMsg.setData(retValue);
		} catch (SPIException e) {
			logger.error(e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
		}
    	return SUCCESS;
    }

    /**
     * 根据渠道充值单号查询线上充值单
     * @param requestMsg
     * @param responseMsg
     * @return
     * @throws ParseException
     */
    @RequestMapping(value = "/queryOnLineRechargeByChaneelNo")
    public String queryOnLineRechargeByChaneelNo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
    	QueryOnLineRechargeByNoCommand command = new QueryOnLineRechargeByNoCommand();
        try {
        	command = SmsUtils.toJavaObject(requestMsg.getData(),QueryOnLineRechargeByNoCommand.class);
            CommandContext ctx = CommandContext.getContext();
            command.setCtx(ctx);
            OnLineRechargeVo onLineRechargeVo = onLineRechargeService.queryOnLineRechargeByChaneelNo(command);
            responseMsg.setData(onLineRechargeVo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            responseMsg.setCode(ErrorCode.SYSTEM_ERROR);
            responseMsg.setMsg(e.getMessage());
            return ERROR;
        }
        return SUCCESS;
    }
 /**
     * 卖家网站-线上充值单导出功能 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/exportOnlineRecharge")
    public String exportOnlineRecharge(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){ 
    	//获取请求参数
    	QueryOnLineRechargeCommand command = SmsUtils.toJavaObject(requestMsg.getData(), QueryOnLineRechargeCommand.class);
    	
    	Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
        if (bpartner == null) {
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>bpartner对象为空");
            return ERROR;
        }
        command.setCustomerCode(bpartner.getValue());
        if (null != command.getPayEndDate()) {
            command.setPayEndDate(DateUtil.spliceDate(command.getPayEndDate()));
        }
    	String path = "";
        try {
        	path = onLineRechargeService.exportOnLineRecharge(command);
            logger.info("卖家网站-线上充值单导出路径：{}", path);
        } catch (SPIException e) {
            logger.error(e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            responseMsg.setData(com.winit.sms.spi.common.constant.Constants.UPLOAD_FA);
            return ERROR;
        }
        responseMsg.setData(path);
        return SUCCESS;
    }
    
    /**
     * 线上充值开具线上电子收据
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping("/generateOnLineElectronicReceipt")
    public String generateOnLineElectronicReceipt(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
    	ModifyOnLineRechargeCommand command = new ModifyOnLineRechargeCommand();
    	try {
    		command = SmsUtils.toJavaObject(requestMsg.getData(), ModifyOnLineRechargeCommand.class);
			CommandContext ctx = CommandContext.getContext();
    		command.setCtx(ctx);
    		String url = onLineRechargeService.generateOnLineElectronicReceipt(command);
    		responseMsg.setData(url);
		} catch (SPIException e) {
			logger.error("线上充值单生成电子收据异常，ID:{},{}", command.getId() + "", e.getMessage());
            responseMsg.setCode(e.getErrorCode());
            responseMsg.setMsg(e.getErrorMsg());
            return ERROR;
		}
    	return SUCCESS;
    }
}
